# Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
# SPDX-License-Identifier: MIT

"""
Entry point script for the DeerFlow project.
"""

import argparse
import asyncio

from InquirerPy import inquirer

from src.config.questions import BUILT_IN_QUESTIONS, BUILT_IN_QUESTIONS_ZH_CN
from src.workflow import run_agent_workflow_async


# ask函数是一个运行智能代理工作流的核心函数。它接受以下参数:
#
# - question: 用户的问题或请求
# - debug: 是否启用调试日志,默认为False
# - max_plan_iterations: 最大计划迭代次数,默认为1次
# - max_step_num: 每个计划最多包含的步骤数,默认为3步
# - enable_background_investigation: 是否在规划前进行网络搜索以增强上下文,默认为True
#
# 该函数使用asyncio.run()运行异步工作流,处理用户输入并返回结果。
# 它是连接用户界面和后端智能代理系统的桥梁。
def ask(
    question,
    debug=False,
    max_plan_iterations=1,
    max_step_num=3,
    enable_background_investigation=True,
):
    """Run the agent workflow with the given question.

    Args:
        question: The user's query or request
        debug: If True, enables debug level logging
        max_plan_iterations: Maximum number of plan iterationsœ
        max_step_num: Maximum number of steps in a plan
        enable_background_investigation: If True, performs web search before planning to enhance context
    """
    asyncio.run(
        run_agent_workflow_async(
            user_input=question,
            debug=debug,
            max_plan_iterations=max_plan_iterations,
            max_step_num=max_step_num,
            enable_background_investigation=enable_background_investigation,
        )
    )


def main(
    debug=False,
    max_plan_iterations=1,
    max_step_num=3,
    enable_background_investigation=True,
):
    """交互式问答模式的主函数。
    
    该函数实现了以下功能:
    1. 提供语言选择功能(中文/英文)
    2. 根据选择的语言展示内置问题列表
    3. 允许用户从内置问题中选择或输入自定义问题
    4. 调用智能代理工作流处理用户问题
    
    函数参数:
        debug (bool): 是否启用调试日志,默认False
        max_plan_iterations (int): 最大计划迭代次数,默认1次
        max_step_num (int): 每个计划最多包含的步骤数,默认3步
        enable_background_investigation (bool): 是否在规划前进行网络搜索以增强上下文,默认True
    
    工作流程:
    1. 通过inquirer.select()让用户选择界面语言
    2. 根据语言选择加载对应的内置问题列表
    3. 让用户从内置问题中选择,或选择输入自定义问题
    4. 如果用户选择自定义问题,则通过inquirer.text()获取输入
    5. 最后调用ask()函数执行智能代理工作流
    """
    # 首先选择界面语言
    language = inquirer.select(
        message="Select language / 选择语言:",
        choices=["English", "中文"],
    ).execute()

    # 根据语言选择加载对应的问题列表
    questions = (
        BUILT_IN_QUESTIONS if language == "English" else BUILT_IN_QUESTIONS_ZH_CN
    )
    ask_own_option = (
        "[Ask my own question]" if language == "English" else "[自定义问题]"
    )

    # 让用户选择问题
    initial_question = inquirer.select(
        message=(
            "What do you want to know?" if language == "English" else "您想了解什么?"
        ),
        choices=[ask_own_option] + questions,
    ).execute()

    # 如果用户选择自定义问题,则获取用户输入
    if initial_question == ask_own_option:
        initial_question = inquirer.text(
            message=(
                "What do you want to know?"
                if language == "English"
                else "您想了解什么?"
            ),
        ).execute()

    # 将所有参数传递给ask函数执行智能代理工作流
    ask(
        question=initial_question,
        debug=debug,
        max_plan_iterations=max_plan_iterations,
        max_step_num=max_step_num,
        enable_background_investigation=enable_background_investigation,
    )

if __name__ == "__main__":
    # 设置命令行参数解析器
    # 创建一个ArgumentParser对象用于处理命令行参数
    parser = argparse.ArgumentParser(description="Run the Deer")
    
    # 添加query参数,用于接收用户查询内容
    # nargs="*"表示可以接收0个或多个参数
    parser.add_argument("query", nargs="*", help="The query to process")
    
    # 添加--interactive参数,用于切换交互模式
    # action="store_true"表示该参数为布尔标志,存在则为True
    parser.add_argument(
        "--interactive",
        action="store_true", 
        help="Run in interactive mode with built-in questions",
    )
    
    # 添加--max_plan_iterations参数,控制计划迭代的最大次数
    # type=int指定参数类型为整数,default=1设置默认值为1
    parser.add_argument(
        "--max_plan_iterations",
        type=int,
        default=1,
        help="Maximum number of plan iterations (default: 1)",
    )
    
    # 添加--max_step_num参数,控制每个计划中步骤的最大数量
    # 默认值为3步
    parser.add_argument(
        "--max_step_num",
        type=int,
        default=3,
        help="Maximum number of steps in a plan (default: 3)",
    )
    
    # 添加--debug参数,用于启用调试日志
    parser.add_argument("--debug", action="store_true", help="Enable debug logging")
    
    # 添加--no-background-investigation参数,用于禁用背景调查
    # action="store_false"表示参数存在时将值设为False
    # dest指定存储该参数值的属性名
    parser.add_argument(
        "--no-background-investigation",
        action="store_false",
        dest="enable_background_investigation",
        help="Disable background investigation before planning",
    )

    # 解析命令行参数
    args = parser.parse_args()

    if args.interactive:
        # 如果使用交互模式,调用main函数并传入命令行参数
        main(
            debug=args.debug,
            max_plan_iterations=args.max_plan_iterations,
            max_step_num=args.max_step_num,
            enable_background_investigation=args.enable_background_investigation,
        )
    else:
        # 非交互模式下,从命令行参数或用户输入获取查询内容
        if args.query:
            # 如果提供了query参数,将多个参数用空格连接成字符串
            user_query = " ".join(args.query)
        else:
            # 否则通过标准输入获取用户查询
            user_query = input("Enter your query: ")

        # 使用获取的参数调用ask函数执行智能代理工作流
        ask(
            question=user_query,
            debug=args.debug,
            max_plan_iterations=args.max_plan_iterations,
            max_step_num=args.max_step_num,
            enable_background_investigation=args.enable_background_investigation,
        )
